<!DOCTYPE html>
<html>
<head>
    <title>Piston in Cylinder Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #999;
            background-color: white;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="800" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');
        ctx.font = '18px Arial';
        ctx.lineWidth = 1;
        ctx.textBaseline = 'middle';

        // --- Common values ---
        const cylinderOuterWidth = 180;
        const cylinderInnerWidth = 140;
        const cylinderHeight = 280;
        const cylinderWallThickness = (cylinderOuterWidth - cylinderInnerWidth) / 2;
        const pistonHeight = 40;
        const travelDistance = 140;

        const leftCylinderX = 90;
        const rightCylinderX = 530;
        const cylinderY = 60;

        // --- Left Diagram: Maximum Height ---

        // Cylinder Body (Grey Part)
        ctx.fillStyle = '#D3D3D3'; // Light grey
        ctx.fillRect(leftCylinderX, cylinderY, cylinderOuterWidth, cylinderHeight);

        // Cylinder Inner (White Part)
        ctx.fillStyle = 'white';
        ctx.fillRect(leftCylinderX + cylinderWallThickness, cylinderY, cylinderInnerWidth, cylinderHeight + 1);

        // Piston at max height
        const pistonMaxTopY = cylinderY + 40;
        const pistonX = leftCylinderX + cylinderWallThickness;
        ctx.fillStyle = 'white';
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.fillRect(pistonX, pistonMaxTopY, cylinderInnerWidth, pistonHeight);
        ctx.strokeRect(pistonX, pistonMaxTopY, cylinderInnerWidth, pistonHeight);

        // Piston rings
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(pistonX, pistonMaxTopY + 14);
        ctx.lineTo(pistonX + cylinderInnerWidth, pistonMaxTopY + 14);
        ctx.moveTo(pistonX, pistonMaxTopY + 20);
        ctx.lineTo(pistonX + cylinderInnerWidth, pistonMaxTopY + 20);
        ctx.moveTo(pistonX, pistonMaxTopY + 26);
        ctx.lineTo(pistonX + cylinderInnerWidth, pistonMaxTopY + 26);
        ctx.stroke();

        // Cylinder outlines (inner walls)
        ctx.beginPath();
        ctx.moveTo(leftCylinderX + cylinderWallThickness, cylinderY);
        ctx.lineTo(leftCylinderX + cylinderWallThickness, cylinderY + cylinderHeight);
        ctx.moveTo(leftCylinderX + cylinderOuterWidth - cylinderWallThickness, cylinderY);
        ctx.lineTo(leftCylinderX + cylinderOuterWidth - cylinderWallThickness, cylinderY + cylinderHeight);
        ctx.stroke();

        // Labels for left diagram
        ctx.fillStyle = 'black';
        ctx.textAlign = 'right';
        ctx.fillText('cylinder', leftCylinderX - 15, cylinderY + 30);
        ctx.beginPath();
        ctx.moveTo(leftCylinderX - 10, cylinderY + 30);
        ctx.lineTo(leftCylinderX, cylinderY + 30);
        ctx.stroke();

        ctx.fillText('piston', leftCylinderX - 15, pistonMaxTopY + 20);
        ctx.beginPath();
        ctx.moveTo(leftCylinderX - 10, pistonMaxTopY + 20);
        ctx.lineTo(pistonX, pistonMaxTopY + 20);
        ctx.stroke();

        // Bottom text for left diagram
        ctx.textAlign = 'center';
        ctx.fillText('maximum height', leftCylinderX + cylinderOuterWidth / 2, cylinderY + cylinderHeight + 30);

        // --- Right Diagram: Minimum Height ---

        // Cylinder Body
        ctx.fillStyle = '#D3D3D3';
        ctx.fillRect(rightCylinderX, cylinderY, cylinderOuterWidth, cylinderHeight);

        // Cylinder Inner
        ctx.fillStyle = 'white';
        ctx.fillRect(rightCylinderX + cylinderWallThickness, cylinderY, cylinderInnerWidth, cylinderHeight + 1);

        // Piston at min height
        const pistonMinTopY = pistonMaxTopY + travelDistance;
        const pistonRightX = rightCylinderX + cylinderWallThickness;
        ctx.fillStyle = 'white';
        ctx.strokeStyle = 'black';
        ctx.lineWidth = 1.5;
        ctx.fillRect(pistonRightX, pistonMinTopY, cylinderInnerWidth, pistonHeight);
        ctx.strokeRect(pistonRightX, pistonMinTopY, cylinderInnerWidth, pistonHeight);

        // Piston rings
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(pistonRightX, pistonMinTopY + 14);
        ctx.lineTo(pistonRightX + cylinderInnerWidth, pistonMinTopY + 14);
        ctx.moveTo(pistonRightX, pistonMinTopY + 20);
        ctx.lineTo(pistonRightX + cylinderInnerWidth, pistonMinTopY + 20);
        ctx.moveTo(pistonRightX, pistonMinTopY + 26);
        ctx.lineTo(pistonRightX + cylinderInnerWidth, pistonMinTopY + 26);
        ctx.stroke();

        // Cylinder outlines
        ctx.beginPath();
        ctx.moveTo(rightCylinderX + cylinderWallThickness, cylinderY);
        ctx.lineTo(rightCylinderX + cylinderWallThickness, cylinderY + cylinderHeight);
        ctx.moveTo(rightCylinderX + cylinderOuterWidth - cylinderWallThickness, cylinderY);
        ctx.lineTo(rightCylinderX + cylinderOuterWidth - cylinderWallThickness, cylinderY + cylinderHeight);
        ctx.stroke();

        // Labels for right diagram
        ctx.fillStyle = 'black';
        ctx.textAlign = 'left';
        ctx.fillText('cylinder', rightCylinderX + cylinderOuterWidth + 15, cylinderY + 30);
        ctx.beginPath();
        ctx.moveTo(rightCylinderX + cylinderOuterWidth + 10, cylinderY + 30);
        ctx.lineTo(rightCylinderX + cylinderOuterWidth, cylinderY + 30);
        ctx.stroke();

        ctx.fillText('piston', rightCylinderX + cylinderOuterWidth + 15, pistonMinTopY + 20);
        ctx.beginPath();
        ctx.moveTo(rightCylinderX + cylinderOuterWidth + 10, pistonMinTopY + 20);
        ctx.lineTo(pistonRightX + cylinderInnerWidth, pistonMinTopY + 20);
        ctx.stroke();

        // Bottom text
        ctx.textAlign = 'center';
        ctx.fillText('minimum height', rightCylinderX + cylinderOuterWidth / 2, cylinderY + cylinderHeight + 30);

        // --- Center Annotation ---
        const annotationLineX = (leftCylinderX + cylinderOuterWidth + rightCylinderX) / 2;

        // Dashed lines
        ctx.beginPath();
        ctx.setLineDash([5, 4]);
        ctx.moveTo(pistonX + cylinderInnerWidth, pistonMaxTopY);
        ctx.lineTo(annotationLineX, pistonMaxTopY);
        ctx.moveTo(annotationLineX, pistonMinTopY);
        ctx.lineTo(pistonRightX, pistonMinTopY);
        ctx.stroke();

        // Vertical line with arrows
        ctx.setLineDash([]);
        ctx.beginPath();
        ctx.moveTo(annotationLineX, pistonMaxTopY);
        ctx.lineTo(annotationLineX, pistonMinTopY);
        // Top arrow
        ctx.moveTo(annotationLineX, pistonMaxTopY);
        ctx.lineTo(annotationLineX - 5, pistonMaxTopY + 8);
        ctx.moveTo(annotationLineX, pistonMaxTopY);
        ctx.lineTo(annotationLineX + 5, pistonMaxTopY + 8);
        // Bottom arrow
        ctx.moveTo(annotationLineX, pistonMinTopY);
        ctx.lineTo(annotationLineX - 5, pistonMinTopY - 8);
        ctx.moveTo(annotationLineX, pistonMinTopY);
        ctx.lineTo(annotationLineX + 5, pistonMinTopY - 8);
        ctx.stroke();

        // Text for dimension
        ctx.textAlign = 'left';
        ctx.fillText('9.8 cm', annotationLineX + 10, (pistonMaxTopY + pistonMinTopY) / 2);

        // --- Figure Caption ---
        ctx.textAlign = 'center';
        ctx.fillText('Fig. 3.1', canvas.width / 2, canvas.height - 25);
    </script>
</body>
</html>